package cn.schoolwow.workflow.module.task.action.flow.complete.nodeType.gateway;

import cn.schoolwow.quickdao.domain.transaction.Transaction;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.workflow.domain.deploy.DeployGatewayPositionType;
import cn.schoolwow.workflow.entity.WorkFlowInstance;
import cn.schoolwow.workflow.entity.WorkFlowNode;
import cn.schoolwow.workflow.entity.WorkFlowNodeJump;
import cn.schoolwow.workflow.module.task.action.domain.CompleteTaskOption;
import cn.schoolwow.workflow.module.task.action.flow.complete.nodeType.gateway.common.CompleteGatewayEndNodeCommonFlow;
import cn.schoolwow.workflow.module.task.action.flow.complete.nodeType.gateway.common.SetCurrentGatewayNodeCommonFlow;
import cn.schoolwow.workflow.module.task.action.flow.complete.transaction.InsertWorkFlowTaskFlow;

import java.util.List;

public class HandleParallelGatewayFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        flowContext.executeFlowList(new SetCurrentGatewayNodeCommonFlow());
        checkParallelGatewayStart(flowContext);
        checkParallelGatewayEnd(flowContext);
    }

    @Override
    public String name() {
        return "处理并行网关流程";
    }

    private void checkParallelGatewayStart(FlowContext flowContext){
        WorkFlowNode gatewayNode = flowContext.checkData("gatewayNode", WorkFlowNode.class);
        DeployGatewayPositionType deployGatewayPositionType = flowContext.checkInstanceData(DeployGatewayPositionType.class);

        if(!DeployGatewayPositionType.Start.equals(deployGatewayPositionType)){
            return;
        }
        WorkFlowInstance workFlowInstance = flowContext.checkInstanceData(WorkFlowInstance.class);
        Transaction transaction = flowContext.checkInstanceData(Transaction.class);
        CompleteTaskOption completeTaskOption = flowContext.checkInstanceData(CompleteTaskOption.class);

        //查询后继节点列表
        List<WorkFlowNode> successorNodeList = transaction.query(WorkFlowNode.class)
                .joinTable(WorkFlowNodeJump.class, "id", "nextNodeId")
                .addQuery("definitionId", gatewayNode.getDefinitionId())
                .addQuery("currentNodeId", gatewayNode.getId())
                .done()
                .execute()
                .getList();
        if(successorNodeList.isEmpty()){
            throw new IllegalArgumentException("并行网关["+gatewayNode.getName()+"]没有后继节点列表!");
        }
        for(WorkFlowNode currentNextNode:successorNodeList){
            //可能出现死循环
            flowContext.startFlow(new InsertWorkFlowTaskFlow())
                    .putCurrentCompositeFlowData("nextNode", currentNextNode)
                    .execute();
        }
        if(successorNodeList.size()==1){
            completeTaskOption.shouldUpdateInstanceCurrentNodeId = true;
            workFlowInstance.setWorkFlowNodeId(successorNodeList.get(0).getId());
        }
    }

    private void checkParallelGatewayEnd(FlowContext flowContext){
        DeployGatewayPositionType deployGatewayPositionType = flowContext.checkInstanceData(DeployGatewayPositionType.class);

        if(!DeployGatewayPositionType.End.equals(deployGatewayPositionType)){
            return;
        }

        flowContext.executeFlowList(new CompleteGatewayEndNodeCommonFlow());
    }

}
